package com.zhaorujie.rpc.bootstrap;

import com.zhaorujie.rpc.core.RpcProperties;
import com.zhaorujie.rpc.core.exception.RpcException;
import com.zhaorujie.rpc.core.remoting.provider.RpcProviderFactory;
import com.zhaorujie.rpc.core.remoting.provider.annotain.RpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.Map;

/**
 * @author 赵汝杰
 * @version v1.0
 * @description RpcSpringProviderFactory
 * @date 2024/3/5
 **/
public class RpcSpringProviderFactory extends RpcProviderFactory implements ApplicationContextAware, InitializingBean, DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(RpcSpringProviderFactory.class);

    private final RpcProperties rpcProperties;
    private volatile boolean startServer = false;

    public RpcSpringProviderFactory(RpcProperties rpcProperties) {
        this.rpcProperties = rpcProperties;
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(RpcService.class);
        if (!serviceBeanMap.isEmpty()) {
            startServer = true;
            serviceBeanMap.forEach((key, serviceBean) -> {
                if (serviceBean.getClass().getInterfaces().length == 0) {
                    throw new RpcException("rpc service(RpcService) must inherit interface.");
                }
                RpcService rpcService = serviceBean.getClass().getAnnotation(RpcService.class);
                String interfaceName = serviceBean.getClass().getInterfaces()[0].getName();
                String version = rpcService.version();
                long timeout = rpcService.timeout();

                super.addService(interfaceName, version, timeout, serviceBean);
            });
        }
    }

    @Override
    public void afterPropertiesSet() {
        logger.debug("RpcSpringProviderFactory afterPropertiesSet");
        if (startServer) {
            super.init(rpcProperties);
        }
    }

    @Override
    public void destroy() {
        logger.debug("RpcSpringProviderFactory destroy");
        if (startServer) {
            super.destroy();
        }
    }
}
